﻿using System;
using System.Text.RegularExpressions;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Globalization;
using System.Text;

namespace SPUtilities.ManageGroupsPerUser
{
    /// <summary>
    /// Extension methods úteis, baseado somente no .net Framework 3.5
    /// </summary>
    public static class AspNetExtensions
    {     
        /// <summary>
        /// Converte para String ou retorna String.Empty em caso de erro.
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public static String ToSafeString(this Object o)
        {
            String returnValue = String.Empty;
            if (o != null)
            {
                try
                {
                    returnValue = o.ToString();
                }
                catch { }
            }
            return returnValue;
        }

        /// <summary>
        /// Converte para Int32 ou retorna zero em caso de erro.
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public static int ToSafeInt32(this Object o)
        {
            Int32 returnValue = 0;
            if (o != null)
            {
                try
                {
                    String returnValueString = o.ToSafeString();
                    Int32.TryParse(returnValueString, out returnValue);
                }
                catch { }
            }
            return returnValue;
        }
        /// <summary>
        /// Converte para Int32 ou retorna zero em caso de erro.
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public static Boolean ToSafeBool(this Object o)
        {
            Boolean returnValue = false;
            if (o != null)
            {
                try
                {
                    String returnValueString = o.ToSafeString();
                    if (returnValueString == "1") {
                        return true;
                    }
                    Boolean.TryParse(returnValueString, out returnValue);
                }
                catch { }
            }
            return returnValue;
        }

        /// <summary>
        /// Converte para DateTime ou retorna DateTime.MinValue; em caso de erro.
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public static DateTime ToSafeDateTime(this Object o)
        {
            DateTime returnValue = DateTime.MinValue;
            if (o != null)
            {
                try
                {
                    String returnValueString = o.ToSafeString();
                    DateTime.TryParse(returnValueString, out returnValue);
                }
                catch { }
            }
            return returnValue;
        }

        /// <summary>
        /// Formata valor em bytes para exibição compreensível em relatórios
        /// </summary>
        /// <param name="size"></param>
        /// <returns></returns>
        public static string ToByteSizeString(this int size)
        {
            Double doub = Convert.ToDouble(size);
            if (doub > 1048573)
            {
                return ((doub / 1048573).ToString("F") + "MB").Replace(",00", String.Empty);
            }
            else if (doub > 1024)
            {
                return ((doub / 1024).ToString("F") + "KB").Replace(",00", String.Empty);
            }
            else
            {
                return size.ToString() + "B";
            }
        }

        /// <summary>
        /// Retorna valor do campo da linha da GRID
        /// </summary>
        /// <param name="g">Linha da GRID</param>
        /// <param name="p">Nome do campo</param>
        /// <returns></returns>
        public static string GetField(this GridViewRow g, string p)
        {
            var ctrl = g.FindControl(p);
            if (ctrl is HiddenField) return ((HiddenField)ctrl).Value;
            return ((ITextControl)ctrl).Text;
        }

        /// <summary>
        /// Seta valor do campo na linha da GRID
        /// </summary>
        /// <param name="g">Linha da GRID</param>
        /// <param name="field">Nome do campo</param>
        /// <param name="value">Valor à setar</param>
        public static void SetLabel(this GridViewRow g, string field, string value)
        {
            var ctrl = g.FindControl(field);
            if (ctrl is HiddenField)
            {
                ((HiddenField)ctrl).Value = value;
            };
            ((ITextControl)ctrl).Text = value;
        }

        /// <summary>
        /// Configura ToolTip para campo em uma linha da GRID
        /// </summary>
        /// <param name="g">Linha da GridView</param>
        /// <param name="field">Nome do campo</param>
        /// <param name="value">Tooltip à inserir</param>
        public static void SetToolTip(this GridViewRow g, string field, string value)
        {
            var ctrl = g.FindControl(field);
            if (ctrl is ImageButton)
            {
                ((ImageButton)ctrl).ToolTip = value;
            }
            else if (ctrl is Button)
            {
                ((Button)ctrl).ToolTip = value;
            }
            else if (ctrl is TextBox)
            {
                ((TextBox)ctrl).ToolTip = value;
            }
            else if (ctrl is DropDownList)
            {
                ((DropDownList)ctrl).ToolTip = value;
            }
        }

        /// <summary>
        /// Seta validação de campo manualmente
        /// </summary>
        /// <param name="g">Linha da GridView</param>
        /// <param name="fieldValidator">Nome do controle do validator</param>
        /// <param name="value">Válido/Inválido</param>
        public static void SetValidator(this GridViewRow g, string fieldValidator, bool value)
        {
            var ctrl = g.FindControl(fieldValidator);
            ((IValidator)ctrl).IsValid = value;
        }

        /// <summary>
        /// Obtém valor do validator
        /// </summary>
        /// <param name="g">Linha da GridView</param>
        /// <param name="fieldValidator">Nome do controle do validator</param>
        /// <returns></returns>
        public static bool GetValidatorIsValid(this GridViewRow g, string fieldValidator)
        {
            var ctrl = g.FindControl(fieldValidator);
            return ((IValidator)ctrl).IsValid;
        }

        /// <summary>
        /// Valida se string é um endereço de email ou contato tipo 'nome <email> ' válido
        /// </summary>
        /// <param name="contato"></param>
        /// <returns></returns>
        public static bool IsValidContact(this string contato)
        {
            //Valida se está no formato Nome <email@dominio.tipo> ou email@dominio.tipo            
            string[] separator = new string[] { "<" };
            string[] dadosContato = contato.Split(separator, StringSplitOptions.RemoveEmptyEntries);

            String strAcentosMatch = "[áàâãªÁÀÂÃéèêÉÈÊíìîÍÌÎóòôõºÓÒÔÕúùûÚÙÛçÇ]";

            Regex regexEmailFormat = new Regex(@"^(?("")(""[^""]+?""@)|(([0-9a-z]((\.(?!\.))|[-~\w])*)(?<=[0-9a-z])@))" +
                @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9]{2,17}))$");

            if (dadosContato.Length == 1)
            {
                if (!String.IsNullOrEmpty(dadosContato[0]))
                {
                    if (regexEmailFormat.IsMatch(dadosContato[0]) &&
                         Regex.Matches(dadosContato[0], strAcentosMatch).Count == 0
                        && !dadosContato[0].EndsWith("."))
                    {
                        return true;
                    }
                }
            }
            else if (dadosContato.Length > 1)
            {
                if (!String.IsNullOrEmpty(dadosContato[0]) && !String.IsNullOrEmpty(dadosContato[1]))
                {
                    if (dadosContato[1].EndsWith(">"))
                    {
                        dadosContato[1] = dadosContato[1].Replace(">", "");
                        if (!dadosContato[1].EndsWith(".") &&
                         Regex.Matches(dadosContato[1], strAcentosMatch).Count == 0 &&
                            regexEmailFormat.IsMatch(dadosContato[1].Replace(">", "")))
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// Limpa string removendo caracteres especiais que podem apresentar problemas no envio de email ou criação de pastas.
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string RemoveSpecialCharacters(this string text)
        {
            string strText = text.Trim();

            strText = Regex.Replace(strText, "[áàâãª]", "a");
            strText = Regex.Replace(strText, "[ÁÀÂÃ]", "A");
            strText = Regex.Replace(strText, "[éèê]", "e");
            strText = Regex.Replace(strText, "[ÉÈÊ]", "e");
            strText = Regex.Replace(strText, "[íìî]", "i");
            strText = Regex.Replace(strText, "[ÍÌÎ]", "I");
            strText = Regex.Replace(strText, "[óòôõº]", "o");
            strText = Regex.Replace(strText, "[ÓÒÔÕ]", "O");
            strText = Regex.Replace(strText, "[úùû]", "u");
            strText = Regex.Replace(strText, "[ÚÙÛ]", "U");
            strText = Regex.Replace(strText, "[ç]", "c");
            strText = Regex.Replace(strText, "[Ç]", "C");
            strText = Regex.Replace(strText, @"[^a-zA-Z0-9-_@\.\s\<\>]", "");

            return strText;
        }

        /// <summary>
        /// Converte string para nome de pasta aceitável pelo SharePoint
        /// </summary>
        /// <param name="folderName"></param>
        /// <returns></returns>
        public static string SanitizeFolderName(this string folderName)
        {
           // return Regex.Replace(folderName, @"[^a-zA-Z0-9-_@\.\s\<\>]", "");
            //folderName = Regex.Replace(folderName, @"[-_@\.\s\<\>]", "");
            //i:0#.w|sp2013\administrator .Replace("#", "").Replace("|", "").
            return folderName.Replace(":", "").Replace("\\", "").Replace("//", "").Replace("{", "").Replace("}", "").Replace(".", "").Replace("&", "-");//.Replace(",","-");
        }

        

        public static string RemoveDiacritics(this string stIn)
        {
            string stFormD = stIn.Normalize(NormalizationForm.FormD);
            StringBuilder sb = new StringBuilder();

            for (int ich = 0; ich < stFormD.Length; ich++)
            {
                UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);
                if (uc != UnicodeCategory.NonSpacingMark)
                {
                    sb.Append(stFormD[ich]);
                }
            }

            return (sb.ToString().Normalize(NormalizationForm.FormC));
        }

        public static string NormalizeStringForUrl(this string name)
        {
            String normalizedString = name.RemoveDiacritics();
            StringBuilder stringBuilder = new StringBuilder();

            foreach (char c in normalizedString)
            {
                switch (CharUnicodeInfo.GetUnicodeCategory(c))
                {
                    case UnicodeCategory.LowercaseLetter:
                    case UnicodeCategory.UppercaseLetter:
                    case UnicodeCategory.DecimalDigitNumber:
                    case UnicodeCategory.SpaceSeparator:
                        stringBuilder.Append(c);
                        break;
                    case UnicodeCategory.ConnectorPunctuation:
                    case UnicodeCategory.DashPunctuation:
                        break;
                }
            }
            string result = stringBuilder.ToString();
            return String.Join("", result.Split(new char[] { ' ' }
                , StringSplitOptions.RemoveEmptyEntries)); // remove duplicate spaces
        }
    }
}